
`include "common_header.verilog"

//  *************************************************************************
//  File : pause_qextract_64
//  *************************************************************************
//  This program is controlled by a written license agreement.
//  Unauthorized reproduction or use is expressly prohibited.
//  Copyright (c) 2014 MorethanIP
//  Muenchner Strasse 199, 85757 Karlsfeld, Germany
//  info@morethanip.com
//  http://www.morethanip.com
//  *************************************************************************
//  Designed by : Daniel Koehler, Thomas Schrobenhauser
//  info@morethanip.com
//  *************************************************************************
//  Description : Extract pause quanta values while pause frame is received.
//                Depending on mode, the Link Pause quanta or all quantas
//                for the PFC pause are extracted.
//  Version     : $Id: pause_qextract_64.v,v 1.1 2014/07/11 13:26:44 ts Exp $
//  *************************************************************************

module pause_qextract_64 (
   reset_rxclk,
   xgmii_rxclk,
   xgmii_rxclk_ena,
   pfc_mode,
   rx_d,
   psop,
   pause_quant_val
   );

input   reset_rxclk;                    //  Active High reset for xgmii_rxclk domain
input   xgmii_rxclk;                    //  XGMII receive clock
input   xgmii_rxclk_ena;                //  XGMII receive clock enable
input   pfc_mode;                       //  PFC mode (1) or Link Pause mode (0)
input   [63:0] rx_d;                    //  Frame data
input   psop;                           //  rx_d contains first word following type/opcode fields
output  [135:0] pause_quant_val;        //  Pause Quanta value(s) from rx path

wire    [135:0] pause_quant_val;

reg     [1:0] pld_s;                    //  payload pipe control
reg     [127:0] qval;                   //  quantas; 15:0=quanta0
reg     [7:0] cena;                     //  per class enable


always @(posedge reset_rxclk or posedge xgmii_rxclk)
   begin : process_1
   if (reset_rxclk == 1'b 1)
      begin
      pld_s <= 2'b 00;
      qval <= {128{1'b 0}};
      cena <= {8{1'b 0}};
      end
   else
      begin
      //  CLOCK ENABLE
      if (xgmii_rxclk_ena == 1'b 1)
         begin

         //  get us a pipe word indicator when this is a PFC frame
         //  -----------------------------------------------------
         if (pfc_mode == 1'b 1 & psop == 1'b 1)
            begin
            pld_s <= 2'b 01;
            end
         else
            begin
            pld_s <= {pld_s[0], 1'b 0};
            end

         //  extract from first word after type, depending on mode
         //  -----------------------------------------------------
         if (psop == 1'b 1)
            begin
            if (pfc_mode == 1'b 0)
               begin
                //  standard link pause, quanta is the only content
               qval[15:0] <= {rx_d[7:0], rx_d[15:8]};
               qval[31:16] <= {16{1'b 0}};
               qval[47:32] <= {16{1'b 0}};
               cena <= 8'h 01;
               end
            else
               begin
                //  PFC: quantas for classes 0..2 are in high portion of the word
               qval[15:0] <= {rx_d[23:16], rx_d[31:24]};
               qval[31:16] <= {rx_d[39:32], rx_d[47:40]};
               qval[47:32] <= {rx_d[55:48], rx_d[63:56]};
               cena <= rx_d[15:8];
               end
            end

         //  collect quantas for classes 3..7
         //  --------------------------------
         if (pld_s[0] == 1'b 1)
            begin
            qval[63:48] <= {rx_d[7:0], rx_d[15:8]};
            qval[79:64] <= {rx_d[23:16], rx_d[31:24]};
            qval[95:80] <= {rx_d[39:32], rx_d[47:40]};
            qval[111:96] <= {rx_d[55:48], rx_d[63:56]};
            end

         if (pld_s[1] == 1'b 1)
            begin
            qval[127:112] <= {rx_d[7:0], rx_d[15:8]};
            end
         end
      end
   end

//  present output
assign pause_quant_val = {cena, qval};


endmodule // module pause_qextract_64
